package com.luke.xiaotiaowa.advice;

import com.luke.xiaotiaowa.events.XtwEvent;
import com.luke.xiaotiaowa.events.XtwEvents;
import com.luke.xiaotiaowa.resp.ResponseVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 全局异常处理类
 *
 * @author xiaotiaowa
 * @create 2023/3/23
 */
@Slf4j
@RestControllerAdvice
public class ErrorControllerAdvice {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseVo handlerArgsError(HttpServletResponse resp, MethodArgumentNotValidException e) {
        var bindingResult = e.getBindingResult();
        resp.setStatus(XtwEvents.BAD_REQUEST.getStatus());
        String message = null;
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            if (fieldError != null) {
                message = fieldError.getField() + fieldError.getDefaultMessage();
            }
        }
        return ResponseVo.builder()
                .code(XtwEvents.BAD_REQUEST.getStatus())
                .message(message)
                .build();
    }

    @ExceptionHandler({Exception.class})
    public ResponseVo handlerThrowable(HttpServletRequest req, HttpServletResponse resp, Exception e) {
        log.error("Exception: ", e);
        var responseVo = ResponseVo.builder().build();
        if (e instanceof XtwEvent) {
            var event = (XtwEvent) e;
            resp.setStatus(event.getCode());
            responseVo.setCode(event.getCode());
            responseVo.setMessage(event.getMessage());
        } else {
            resp.setStatus(XtwEvents.INTERNAL_SERVER_ERROR.getStatus());
            responseVo.setCode(XtwEvents.INTERNAL_SERVER_ERROR.getStatus());
            responseVo.setMessage(e.toString());
        }
        return responseVo;
    }
}
